﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using UnityEngine;
using XMLib;

namespace ActionSystem.Core
{
    enum ActionState
    {
        NotExcuting,
        Excuting,
    }
    public sealed class BaseStateAction
    {
        BaseState state;
        public BaseState State=>state;
        
        BaseStateMachine stateMachine;
        public BaseStateMachine StateMachine => stateMachine;
        ActionState actionState = ActionState.NotExcuting;
        BaseStateActionHandler handler;
        public BaseStateActionHandler Handler => handler;        
        BaseStateActionConfig config;
        public BaseStateActionConfig Config => config;

        public BaseStateAction(BaseState state,BaseStateActionConfig config)
        {
            this.state = state;
            this.stateMachine = state.StateMachine;

            this.config = config;
            this.handler = GetActionHandler(config.GetType());
        }

        public int FrameIndex { get; private set; }
        public int LoopCnt { get; private set; }
        /// <summary>
        /// 处于正在执行状态
        /// </summary>
        public bool IsExcuting => actionState == ActionState.Excuting;

        public void SetUpOnState()
        {
            actionState = ActionState.NotExcuting;
            Handler?.OnStateSetUp(this);
        }

        public void UpdateIndexAndLoop(int index,int loop)
        {
            FrameIndex = index;
            LoopCnt = loop;                                    
        }
        public void TryExit()
        {
            //处理exit
            if (IsExcuting && (FrameIndex == config.End || (!Config.Loop && FrameIndex == 0 && LoopCnt >= 1)))
            {
                _Exit();
            }
        }
        public void TryEnter()
        {
            //处理enter
            if (!IsExcuting && FrameIndex == config.Begin)
            {
                _Enter();
            }
        }

        public void RemoveFromState()
        {
            //如果没有退出，则必须退出
            if(IsExcuting)
            {
                _Exit();
            }
            Handler?.OnStateRemove(this);
            actionState = ActionState.NotExcuting;
        }
        #region 拷贝数据,拷贝完就清空      
        object cloneData = null;
        /// <summary>
        /// 获取拷贝的数据，用户调用
        /// </summary>
        /// <returns></returns>
        public object BeforeStateActionData()
        {
            var res = cloneData;
            cloneData = null;
            return res;            
        }
        /// <summary>
        /// 设置clone数据，非用户使用
        /// </summary>
        /// <param name="cloneData">克隆的数据</param>
        /// <returns>是否成功</returns>
        public bool SetNextStateActionData(object cloneData)
        {
            if(this.cloneData==null)
            {
                this.cloneData = cloneData;
                return true;
            }
            return false;
        }
        /// <summary>
        /// 获取存储的clone数据,非用户使用
        /// </summary>
        /// <returns></returns>
        public object GetRawInnerData()
        {
            return Handler?.GetInnerData();
        }
        /// <summary>
        /// 强制退出
        /// </summary>
        public void StopAction()
        {
            _Exit();
        }
        #endregion
        void _Enter()
        {
            actionState = ActionState.Excuting;
            Handler?.Enter(this);
        }
        void _Exit()
        {
            Handler?.Exit(this);
            actionState = ActionState.NotExcuting;
            //清空
            cloneData = null;
        }
        /// <summary>
        /// 重置数据
        /// </summary>
        public void Reset()
        {
            actionState = ActionState.NotExcuting;
            FrameIndex = 0;
            LoopCnt = 0;
        }
        public static BaseStateActionHandler GetActionHandler(Type type)
        {
            BaseStateActionHandler handler = null;
            //具有该参数的类type->Attribute->IIActionHandler
            ActionConfigAttribute config = type.GetCustomAttribute<ActionConfigAttribute>(true);
            Type handlerType = config.handlerType;
            //实例化该类
            handler = Activator.CreateInstance(handlerType) as BaseStateActionHandler;
            if (handler == null)
            {
                throw new RuntimeException($"{handlerType} 类型未继承 {nameof(BaseStateActionHandler)} 接口");
            }
            return handler;
        }
    }
}

